package interview.huawei;

class MyCircularQueue {

    private static class Node {
        int val;
        Node next;

        public Node() {
        }

        public Node(int val) {
            this.val = val;
        }

        public Node(int val, Node next) {
            this.val = val;
            this.next = next;
        }
    }

    private Node head;
    private Node rear;
    private Node front;
    private final int size;
    private int length;

    public MyCircularQueue(int k) {
        head = new Node();
        head.next = null;
        this.size = k;
        this.length = 0;
    }

    public boolean enQueue(int value) {
        if (!isFull()) {
            Node p = new Node(value);
            if (null == head.next) {
                head.next = p;
                p.next = p;
                this.front = p;
                this.rear = p;
            } else {
                //
                p.next = head.next;
                head.next = p;
                rear = p;
                front.next = rear;
            }
            this.length += 1;
            return true;
        } else {
            return false;
        }
    }

    public boolean deQueue() {
        if (!isEmpty()) {
            head.next = rear.next;
            rear = rear.next;
            front.next = rear;
            this.length -= 1;
        }
        return true;
    }

    public int Front() {
        if (isEmpty()) {
            return -1;
        } else {
            return front.val;
        }
    }

    public int Rear() {
        if (isEmpty()) {
            return -1;
        } else {
            return rear.val;
        }
    }

    public boolean isEmpty() {
        return (null == head.next);
    }

    public boolean isFull() {
        return (this.length == this.size);
    }
}

/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * MyCircularQueue obj = new MyCircularQueue(k);
 * boolean param_1 = obj.enQueue(value);
 * boolean param_2 = obj.deQueue();
 * int param_3 = obj.Front();
 * int param_4 = obj.Rear();
 * boolean param_5 = obj.isEmpty();
 * boolean param_6 = obj.isFull();
 */